<!--
 * @description 乾元丹计算器页面
 * @function 计算乾元丹升级所需经验、金钱、等级要求
 * @workflow 用户选择等级→点击计算按钮→显示所需资源信息
 * @author 开发团队
 * @date 2024-01-01
-->

<template>
    <div class='container'>
        <!-- 等级选择按钮组 -->
        <div class="level-selection">
            <div class="section-title">乾元丹选择</div>
            <div class="level-buttons">
                <button v-for="level in qianyuandanLevels" :key="level.id" class="level-btn"
                    :class="{ active: selectedLevels.includes(level.id) }"
                    @click="handleLevelSelectButtonClick(level.id)">
                    {{ level.id }}
                </button>
            </div>
        </div>

        <!-- 等级要求和资源需求显示 -->
        <div v-if="selectedLevels.length > 0" class="info-section">
            <div class="section-title">
                {{ getSectionTitle() }}
            </div>
            <div class="info-grid">
                <div class="info-item">
                    <div class="info-label">正常所需等级</div>
                    <div class="info-value level">{{ getMaxLevelData().normalLevel }}</div>
                </div>
                <div class="info-item">
                    <div class="info-label">
                        {{ getMaxLevelData().minLevel === getMaxLevelData().normalLevel ?
                            '无需突破' : '突破等级' }}
                    </div>
                    <div class="info-value min-level">
                        {{ getMaxLevelData().minLevel === getMaxLevelData().normalLevel ?
                            '无需突破' : getMaxLevelData().minLevel }}
                    </div>
                </div>
                <div class="info-item">
                    <div class="info-label">{{ getExpLabel() }}</div>
                    <div class="info-value exp">{{ formatNumber(getTotalExp()) }}</div>
                </div>
                <div class="info-item">
                    <div class="info-label">{{ getMoneyLabel() }}</div>
                    <div class="info-value money">{{ formatNumber(getTotalMoney()) }}</div>
                </div>
            </div>
        </div>
        <!--特殊提示-->
        <div class="special-tip">
            <div class="section-title">特殊提示</div>
            <div class="special-tip-content">
                <div class="tip-item">1. 乾元丹的升级所需经验、金钱、等级要求是根据游戏内的数据计算得出的。</div>
                <div class="tip-item">2. 只计算正常升级所需经验、金钱、等级要求。</div>
                <div class="tip-item">3. 乾元丹突破是概率性的，不参与结果的计算。</div>
                <div class="tip-item">4. 结果参考官方资料，精确到万。</div>
            </div>
        </div>
    </div>
</template>

<script>
// 结构
import {
    defineComponent,
    onMounted,
    ref,
    watch,
    reactive
} from 'vue';

// 模块化
export default defineComponent({
    name: 'QianyuandanCalculator', // 组件名称
    props: {
        // 接收父组件数据
    },
    components: {
        // 定义子组件
    },
    // 主要是组件内交互事件
    setup(props, ctx) {
        // 乾元丹等级数据
        const qianyuandanLevels = ref([
            {
                id: 1,
                exp: 22340000,
                money: 4470000,
                minLevel: 69,
                normalLevel: 69
            },
            {
                id: 2,
                exp: 22850000,
                money: 5570000,
                minLevel: 89,
                normalLevel: 89
            },
            {
                id: 3,
                exp: 34530000,
                money: 6910000,
                minLevel: 109,
                normalLevel: 109
            },
            {
                id: 4,
                exp: 42520000,
                money: 8500000,
                minLevel: 129,
                normalLevel: 129
            },
            {
                id: 5,
                exp: 51920000,
                money: 10380000,
                minLevel: 129,
                normalLevel: 155
            },
            {
                id: 6,
                exp: 62850000,
                money: 12570000,
                minLevel: 159,
                normalLevel: 159
            },
            {
                id: 7,
                exp: 75420000,
                money: 15080000,
                minLevel: 159,
                normalLevel: 164
            },
            {
                id: 8,
                exp: 75980000,
                money: 15200000,
                minLevel: 168,
                normalLevel: 168
            },
            {
                id: 9,
                exp: 72200000,
                money: 14440000,
                minLevel: 171,
                normalLevel: 171
            }
        ]);

        // 选中的等级
        const selectedLevels = ref([]);

        /**
         * 处理等级选择按钮点击事件
         * @param {number} levelId - 选中的等级ID
         */
        const handleLevelSelectButtonClick = (levelId) => {
            const current = selectedLevels.value;
            const isSelected = current.includes(levelId);

            if (isSelected) {
                // 已选中的情况
                if (current.length === 1) {
                    // 只有1个已选时，点击同一个不取消，保持至少选中1个
                    return;
                }
                // 有2个已选时，点击其中一个则正常取消
                selectedLevels.value = current.filter(id => id !== levelId);
                return;
            }

            // 未选中的情况
            if (current.length < 2) {
                selectedLevels.value = [...current, levelId];
            } else {
                // 已有2个，移除第一个，添加新选择，保持顺序
                selectedLevels.value = [current[1], levelId];
            }
        };

        /**
         * 获取选中的等级数据
         * @returns {object} 选中的等级数据
         */
        const getSelectedLevelData = () => {
            if (selectedLevels.value.length === 0) {
                return {};
            }
            return qianyuandanLevels.value.find(l => l.id === selectedLevels.value[0]);
        };

        /**
         * 获取最大等级数据
         * @returns {object} 最大等级数据
         */
        const getMaxLevelData = () => {
            if (selectedLevels.value.length === 0) {
                return {};
            }
            return qianyuandanLevels.value.find(l => l.id === Math.max(...selectedLevels.value));
        };

        /**
         * 获取标题显示文本
         * @returns {string} 标题文本
         */
        const getSectionTitle = () => {
            if (selectedLevels.value.length === 0) return '';

            if (selectedLevels.value.length === 1) {
                return `第${selectedLevels.value[0]}个乾元丹需要资源`;
            }

            const lower = Math.min(...selectedLevels.value);
            const upper = Math.max(...selectedLevels.value);

            if (upper - lower === 1) {
                // 相邻等级：显示两个等级
                return `第${lower}个和第${upper}个乾元丹需要资源`;
            } else {
                // 不相邻等级：显示范围
                return `第${lower}个到第${upper}个乾元丹需要资源`;
            }
        };

        /**
         * 获取经验标签文本
         * @returns {string} 经验标签文本
         */
        const getExpLabel = () => {
            if (selectedLevels.value.length === 1) return '所需经验';

            const lower = Math.min(...selectedLevels.value);
            const upper = Math.max(...selectedLevels.value);

            if (upper - lower === 1) {
                return '所需经验';
            } else {
                return '累计经验';
            }
        };

        /**
         * 获取金钱标签文本
         * @returns {string} 金钱标签文本
         */
        const getMoneyLabel = () => {
            if (selectedLevels.value.length === 1) return '所需金钱';

            const lower = Math.min(...selectedLevels.value);
            const upper = Math.max(...selectedLevels.value);

            if (upper - lower === 1) {
                return '所需金钱';
            } else {
                return '累计金钱';
            }
        };

        /**
         * 获取累计经验
         * @returns {number} 累计经验
         */
        const getTotalExp = () => {
            if (selectedLevels.value.length === 0) return 0;

            if (selectedLevels.value.length === 1) {
                // 单个等级：显示该等级需要的经验
                const level = qianyuandanLevels.value.find(l => l.id === selectedLevels.value[0]);
                return level ? level.exp : 0;
            }

            // 两个等级的情况
            const lower = Math.min(...selectedLevels.value);
            const upper = Math.max(...selectedLevels.value);

            if (upper - lower === 1) {
                // 相邻等级（如[2,3]）：只计算这两个等级的经验总和
                return qianyuandanLevels.value
                    .filter(l => l.id === lower || l.id === upper)
                    .reduce((sum, l) => sum + l.exp, 0);
            } else {
                // 不相邻等级（如[1,9]）：计算从lower到upper所有等级的经验总和
                return qianyuandanLevels.value
                    .filter(l => l.id >= lower && l.id <= upper)
                    .reduce((sum, l) => sum + l.exp, 0);
            }
        };

        /**
         * 获取累计金钱
         * @returns {number} 累计金钱
         */
        const getTotalMoney = () => {
            if (selectedLevels.value.length === 0) return 0;

            if (selectedLevels.value.length === 1) {
                // 单个等级：显示该等级需要的金钱
                const level = qianyuandanLevels.value.find(l => l.id === selectedLevels.value[0]);
                return level ? level.money : 0;
            }

            // 两个等级的情况
            const lower = Math.min(...selectedLevels.value);
            const upper = Math.max(...selectedLevels.value);

            if (upper - lower === 1) {
                // 相邻等级（如[2,3]）：只计算这两个等级的金钱总和
                return qianyuandanLevels.value
                    .filter(l => l.id === lower || l.id === upper)
                    .reduce((sum, l) => sum + l.money, 0);
            } else {
                // 不相邻等级（如[1,9]）：计算从lower到upper所有等级的金钱总和
                return qianyuandanLevels.value
                    .filter(l => l.id >= lower && l.id <= upper)
                    .reduce((sum, l) => sum + l.money, 0);
            }
        };

        /**
         * 格式化数字显示
         * @param {number} num - 需要格式化的数字
         * @returns {string} 格式化后的字符串
         */
        const formatNumber = (num) => {
            if (num >= 10000) {
                return (num / 10000).toFixed(1) + '万';
            }
            return num.toLocaleString();
        };

        /**
         * 获取阶段性累计经验
         * @param {number} startLevel - 起始等级，默认为0
         * @returns {number} 累计经验
         */
        const getStageTotalExp = (startLevel = 0) => {
            if (selectedLevels.value.length === 0) return 0;

            let totalExp = 0;
            for (let i = startLevel + 1; i <= selectedLevels.value[0]; i++) {
                const level = qianyuandanLevels.value.find(l => l.id === i);
                if (level) {
                    totalExp += level.exp;
                }
            }
            return totalExp;
        };

        /**
         * 获取阶段性累计金钱
         * @param {number} startLevel - 起始等级，默认为0
         * @returns {number} 累计金钱
         */
        const getStageTotalMoney = (startLevel = 0) => {
            if (selectedLevels.value.length === 0) return 0;

            let totalMoney = 0;
            for (let i = startLevel + 1; i <= selectedLevels.value[0]; i++) {
                const level = qianyuandanLevels.value.find(l => l.id === i);
                if (level) {
                    totalMoney += level.money;
                }
            }
            return totalMoney;
        };

        /**
         * 获取阶段性最大等级要求
         * @returns {number} 最大等级要求
         */
        const getStageMaxLevel = () => {
            if (selectedLevels.value.length === 0) return 0;

            let maxLevel = 0;
            for (let i = 1; i <= selectedLevels.value[0]; i++) {
                const level = qianyuandanLevels.value.find(l => l.id === i);
                if (level) {
                    maxLevel = Math.max(maxLevel, level.normalLevel);
                }
            }
            return maxLevel;
        };

        // 这里没有this,直接使用props里数据
        // 进行数据的定义和初始化。object style interactive
        onMounted(() => {
            // 初始化时可以选择第一个等级
            if (qianyuandanLevels.value.length > 0) {
                selectedLevels.value = [qianyuandanLevels.value[0].id];
            }
        });

        return {
            qianyuandanLevels,
            selectedLevels,
            handleLevelSelectButtonClick,
            getSelectedLevelData,
            getMaxLevelData,
            getSectionTitle,
            getExpLabel,
            getMoneyLabel,
            getTotalExp,
            getTotalMoney,
            formatNumber,
            getStageTotalExp,
            getStageTotalMoney,
            getStageMaxLevel
        };
    },
    // 组件之间交互事件
    methods: {

    },
    // 生命周期 - 创建完成（访问DOM元素）
    beforeCreate() {

    },
    // 生命周期 - 创建完成（访问当前this实例）
    created() {

    },
    // 生命周期 - 挂载完成（访问当前this实例）
    mounted() {

    },
    // 生命周期 - 更新之前（访问当前this实例）
    beforeUpdate() {

    },
    // 生命周期 - 更新之前（访问当前this实例）
    updated() {

    },
    // 生命周期 - 销毁之前（访问当前this实例）
    unmounted() {

    },
    // 生命周期 - 组件激活（访问当前this实例）
    activated() {

    },
    // 生命周期 - 组件停用（访问当前this实例）
    deactivated() {

    },
    // 生命周期 - 子孙组件错误时
    errorCaptured() {

    }
});
</script>

<style lang='less' scoped>
@import '../../static/style/common.less';

/* scoped 使用得定义的样式只在本页面内生效  */
.container {
    width: 100%;
    padding: @page-padding;
    background: @color-bg;
    min-height: 100vh;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;

    .level-selection {
        .card();
        .pageContent();
    }

    .level-selection {
        .section-title {
            .sectionTitle();
        }

        .level-buttons {
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: flex-start;
            align-content: flex-start;
            align-items: center;

            .level-btn {
                .btnBase();
                justify-content: flex-start;
                align-content: flex-start;
                margin-left: 20rpx;
                margin-top: 20rpx;
                margin-right: 0;

                &:hover {
                    .btnHover();
                }

                &.active {
                    .btnActive();
                }
            }
        }
    }

    .info-section {
        .card();
        .pageContent();
    }

    .info-section {
        .section-title {
            .sectionTitle();
        }

        .info-grid {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;

            .info-item {
                width: calc(~ " (100% - 100rpx)/2");
                .resultItem();
                margin-bottom: 20rpx;
                text-align: center;

                .info-label {
                    color: @color-text-muted;
                    font-size: @label-size;
                    margin-bottom: 8rpx;
                }

                .info-value {
                    font-size: @title-size;
                    font-weight: bold;

                    &.level {
                        color: #4CAF50;
                    }

                    &.min-level {
                        color: #FF9800;
                    }

                    &.exp {
                        color: #2196F3;
                    }

                    &.money {
                        color: #E91E63;
                    }
                }
            }
        }
    }

    .special-tip {
        .card();
        .pageContent();
    }

    .special-tip {
        .section-title {
            .sectionTitle();
        }

        .special-tip-content {
            color: @color-text-muted;
            font-size: @label-size;
            line-height: 1.8;

            .tip-item {
                position: relative;
                margin: 12rpx 0;
                padding-left: 28rpx;

                &::before {
                    content: '-';
                    position: absolute;
                    left: 0;
                    top: 0;
                    color: #999;
                    line-height: 1.8;
                }
            }

            .em {
                color: @color-text;
                font-weight: 700;
            }
        }
    }
}
</style>